﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using BoxGame;
using BoxGame.Beings;

namespace BoxGame.Interface
{
    class Gui
    {
        Game1 game1;
        GraphicsDevice device;

        // Mauszeiger
        // Texture2D mausZeiger;

        // Groesse der Icons in der Bitmap.
        const int iconSize = 32;

        SpriteFont font;

        // Der angeklickte und hervorgehobene Slot.
        int geklickterSlot;

        bool dragndrop; //Dragndrop Modus
        bool mausHatIcon = false;

        Texture2D kompassTexture;
        Vector2 kompassPos;
        Vector2 kompassOrigin;
        float kompassWinkel;
        float kompassScale;

        // "Slot" fuer Dragndrop wenn das
        // Icon am Mauszeiger haengt.
        Slot mausSlot;
        Rectangle mausDestination;
        Rectangle mausSource;
        Color mausIconColor;

        Player spieler;

        Texture2D kompassRingTexture;
        Vector2 kompassRingOrigin;

        Texture2D qBarTexture;
        Vector2 qBarPos;
        Vector2 qBarOrigin;

        Texture2D qBarBG;

        Texture2D hpFrameTexture;
        Vector2 hpFramePos;

        Texture2D hpBarTexture;
        Rectangle hpPercent;

        Texture2D manaBarTexture;
        Rectangle manaPercent;

        Texture2D iconTexture;

        Rectangle[] slotDestination;
        Rectangle[] slotSource;

        public Qbar leiste;

        Chatbox chatBox;

        public Gui(Game1 mgame1, GraphicsDevice mdevice, Player mspieler)
        {
            // Mit der Hauptklasse bekannt machen.
            game1 = mgame1;

            // Das Grafik Device bekannt machen.
            device = mdevice;

            // Den Spieler uebergeben.
            spieler = mspieler;

            // Schnellleiste (Qbar) erstellen.
            leiste = new Qbar();

            // Dieses Rechteck ist die Begrenzung für den
            // Trefferpunkt Balken, den wir in das Rechteck reinmalen.
            // Indem man die Groesse des Rechtecks aendert, kann man
            // die Laenge des angezeigten Balkens aendern.
            // Das gleiche fuer Mana und alle anderen Balken die
            // uns noch einfallen.
            // Wieso hat Visual Studio keine Rechtschreibpruefung??
            hpPercent = new Rectangle(200, 200, 200, 16);
            manaPercent = new Rectangle(200, 200, 200, 16);

            // Rechtecke fuer Icons auf der Leiste.
            slotDestination = new Rectangle[10];
            slotSource = new Rectangle[10];
            for (int i = 0; i < 10; i++)
            {
                slotDestination[i] = new Rectangle(0, 0, 68, 68);
                slotSource[i] = new Rectangle(0, 0, iconSize, iconSize);
            }
      
            // Mausslot und entsprechende Rechtecke
            // fuer Dragndrop, damit das gezogene
            // Icon an der Maus kleben bleibt.
            mausSlot = new Slot();
            mausDestination = new Rectangle(0, 0, 64, 64);
            mausSource = new Rectangle(0, 0, iconSize, iconSize);
            mausIconColor = Color.White;

            // Chatbox erstellen
            chatBox = new Chatbox(game1, device);

        }

        /// <summary>
        /// Initialisiert die Textur-Positionen.
        /// Wird u.A. aufgerufen, wenn die Fenstergroesse
        /// geaendert wird, oder andere GUI Aktionen
        /// ausgeführt werden.
        /// </summary>
        public void guiUpdaten()
        {
            // Kompass
            kompassPos.X = device.Viewport.Width - 120;
            kompassPos.Y = 120f;
            kompassOrigin.X = kompassTexture.Width / 2;
            kompassOrigin.Y = kompassTexture.Height / 2;
            kompassScale = 0.6f;

            // Kompassring
            kompassRingOrigin.X = kompassRingTexture.Width / 2;
            kompassRingOrigin.Y = kompassRingTexture.Height / 2;

            // Schnellleiste (QBar)
            qBarPos.X = (device.Viewport.Width / 2) - (qBarTexture.Width / 2);
            qBarPos.Y = device.Viewport.Height - 90;
            qBarOrigin.X = 0;
            qBarOrigin.Y = 0;


            // Rechtecke für Icons um die Leiste zu belegen.
            for (int i = 0; i < 10; i++)
            {
                slotDestination[i].X = ((int)qBarPos.X + 5) + i * 73;
                slotDestination[i].Y = (int)qBarPos.Y + 5;
                if (leiste.iconIdGeben(i) == -1)
                {
                    slotSource[i].X = -100;
                    slotSource[i].Y = -100;
                }
                else
                {
                    slotSource[i].X = 32 * (leiste.iconIdGeben(i) % 10);
                    slotSource[i].Y = 32 * (leiste.iconIdGeben(i) / 10);
                }
            }

            // Rechteck für den Mausslot updaten.
            // Dazu das entsprechende Icon darstellen.
            // Unsichtbar, wenn grad nicht gedragt wird.
            mausSource.X = 32 * (mausSlot.gibIconID() % 10);
            mausSource.Y = 32 * (mausSlot.gibIconID() / 10);
            if (mausHatIcon)
            {
                mausIconColor = Color.White;
            }
            else
            {
                mausIconColor = Color.Transparent;
            }

            // HP Anzeige Hintergrund.
            hpFramePos.X = qBarPos.X;
            hpFramePos.Y = qBarPos.Y - 95f;

            // TODO: Eigene Updatefunktion für die TP und andere
            // Anzeigeelemente damit wir nicht bei jeden Angriff etc.
            // gleich alle GUI Elemente neu ausrichten müssen.
            // Relative Balkenlaenge berechnen:
            if (spieler.hpMax > 0)
            {
                hpPercent.Width = (int)((200 / spieler.hpMax) * spieler.hpCurrent); // weil der Balken 200 Pixel lang ist
            }
            else
            {
                hpPercent.Width = 0;
            }
            hpPercent.X = (int)hpFramePos.X + 67;
            hpPercent.Y = (int)hpFramePos.Y + 24;
            // Mana
            if (spieler.manaMax > 0)
            {
                manaPercent.Width = (int)((200 / spieler.manaMax) * spieler.manaCurrent);
            }
            else
            {
                manaPercent.Width = 0;
            }
            manaPercent.X = (int)hpFramePos.X + 67;
            manaPercent.Y = (int)hpFramePos.Y + 52;

            // Chatbox
            chatBox.posUpdaten();
        }

        public void texturenLaden()
        {
            // Texturen laden.
            // mausZeiger = game1.Content.Load<Texture2D>(@"Gui\Mauszeiger");
            kompassTexture = game1.Content.Load<Texture2D>(@"Gui\Kompass");
            kompassRingTexture = game1.Content.Load<Texture2D>(@"Gui\Kompassring");
            qBarTexture = game1.Content.Load<Texture2D>(@"Gui\Qbar");
            qBarBG = game1.Content.Load<Texture2D>(@"Gui\Qbarbg");
            hpFrameTexture = game1.Content.Load<Texture2D>(@"Gui\Hpanzeige");
            hpBarTexture = game1.Content.Load<Texture2D>(@"Gui\Hpbar");
            manaBarTexture = game1.Content.Load<Texture2D>(@"Gui\Manabar");
            iconTexture = game1.Content.Load<Texture2D>(@"Gui\icons");
            font = game1.Content.Load<SpriteFont>("Spritefont1");
        }

        public void malen()
        {
            int mausX = Mouse.GetState().X;
            int mausY = Mouse.GetState().Y;
            kompassWinkel = game1.cameraYaw;
            game1.spriteBatch.Draw(kompassTexture, kompassPos, null, Color.White, MathHelper.ToRadians(kompassWinkel), kompassOrigin, kompassScale, SpriteEffects.None, 0.5f);
            game1.spriteBatch.Draw(kompassRingTexture, kompassPos, null, Color.White, 0.0f, kompassRingOrigin, kompassScale, SpriteEffects.None, 0.4f);
            game1.spriteBatch.Draw(qBarBG, qBarPos, null, new Color(255, 255, 255, 128), 0.0f, qBarOrigin, 1.0f, SpriteEffects.None, 0.7f);
            game1.spriteBatch.Draw(qBarTexture, qBarPos, null, Color.White, 0.0f, qBarOrigin, 1.0f, SpriteEffects.None, 0.5f);
            game1.spriteBatch.Draw(hpFrameTexture, hpFramePos, null, Color.White, 0.0f, new Vector2(0f, 0f), 1.0f, SpriteEffects.None, 0.5f);
            game1.spriteBatch.Draw(hpBarTexture, hpPercent, null, Color.White, 0.0f, new Vector2(0f, 0f), SpriteEffects.None, 0.4f);
            game1.spriteBatch.Draw(manaBarTexture, manaPercent, null, Color.White, 0.0f, new Vector2(0f, 0f), SpriteEffects.None, 0.4f);
            for (int i = 0; i < 10; i++)
            {
                game1.spriteBatch.Draw(iconTexture, slotDestination[i], slotSource[i], leiste.getFarbe(i), 0.0f, new Vector2(0f, 0f), SpriteEffects.None, 0.6f);
            }
            // Mauszeiger malen.
            // game1.spriteBatch.Draw(mausZeiger, new Vector2(mausX, mausY), null, Color.White);
            if (mausHatIcon)
            {
                mausDestination.X = mausX;
                mausDestination.Y = mausY;
                game1.spriteBatch.Draw(iconTexture, mausDestination, mausSource, mausIconColor, 0.0f, new Vector2(0f, 0f), SpriteEffects.None, 0.3f);
            }
            // Tooltip malen
            if (( mausX > qBarPos.X) && (mausY > qBarPos.Y))
            {
                bool slotgefunden = false;
                int slotzaehler = 0;
                while (!slotgefunden && (slotzaehler < 10))
                {
                    if (slotDestination[slotzaehler].Contains(new Point(mausX, mausY)))
                    {
                        if (!leiste.isEmpty(slotzaehler))
                        {
                            slotgefunden = true;
                            game1.spriteBatch.DrawString(font, leiste.gibEffectName(slotzaehler), new Vector2(mausX, mausY - 100), Color.White);
                        }
                    }
                    slotzaehler += 1;
                }
            }
            // Chatbox malen.
            chatBox.malen();
        }

        // Wenn game1 mitteilt, dass die l. Maustaste gedrueckt wurde.
        public void mausKlick(int mx, int my)
        {
            // Wenn wir kein Icon an der Maus haben.
            if (!mausHatIcon)
            {
                // Schauen, ob der Klick im Bereich der Leiste liegt.
                if ((mx > qBarPos.X) && (my > qBarPos.Y))
                {
                    // Schauen, welcher Slot der Leiste getroffen wurde.
                    bool slotgefunden = false;
                    int slotzaehler = 0;
                    while (!slotgefunden && (slotzaehler < 10))
                    {
                        if (slotDestination[slotzaehler].Contains(new Point(mx, my)))
                        {
                            if (!leiste.isEmpty(slotzaehler))
                            {
                                slotgefunden = true;
                                geklickterSlot = slotzaehler;
                                leiste.setFarbe(slotzaehler, Color.DarkGray);
                                leiste.slotAktivieren(slotzaehler);
                                chatBox.schreiben("Slot " + slotzaehler.ToString() + " geklickt.\n");
                            }
                        }
                        slotzaehler += 1;
                    }
                }
            }
        }

        // Wenn game1 mitteilt, dass die l. Maustaste losgelassen wurde.
        public void mausLoslassen(int mx, int my)
        {
            // Dragndrop Modus in jedem Fall beenden.
            dragndrop = false;

            // Hervorhebung des zuletzt geklickten
            // Slots abschalten.
            if (!leiste.isEmpty(geklickterSlot))
            {
                leiste.setFarbe(geklickterSlot, Color.White);
            }

            // Wenn an der Maus ein Icon hängt.
            if (mausHatIcon)
            {
                // Schauen, welcher Slot der Leiste getroffen wurde.
                bool slotgefunden = false;
                int slotzaehler = 0;
                while (!slotgefunden && (slotzaehler < 10))
                {
                    if (slotDestination[slotzaehler].Contains(new Point(mx, my)))
                    {
                        slotgefunden = true;
                        if (leiste.isEmpty(slotzaehler))
                        {
                            leiste.slotBelegen(slotzaehler, mausSlot.effektGeben());
                            mausSlot.leeren();
                            mausIconColor = Color.Transparent;
                            mausHatIcon = false;
                            leiste.setFarbe(slotzaehler, Color.White);
                            this.guiUpdaten();
                        }
                        else
                        {
                            Slot hilfSlot = new Slot();
                            hilfSlot.effektBelegen(leiste.effectGeben(slotzaehler));
                            leiste.slotBelegen(slotzaehler, mausSlot.effektGeben());
                            mausSlot.effektBelegen(hilfSlot.effektGeben());
                            mausHatIcon = true;
                            leiste.setFarbe(slotzaehler, Color.White);
                            mausIconColor = Color.White;
                            this.guiUpdaten();
                        }
                    }
                    slotzaehler += 1;
                }
                if (!slotgefunden) // Offenbar im Nichts losgelassen.
                {
                    mausHatIcon = false;
                    mausSlot.leeren();
                    mausIconColor = Color.Transparent;
                    this.guiUpdaten();
                }
            }
        }

        // Dragndrop
        public void dndStart(int mx, int my)
        {
            if (!dragndrop) // Nur machen, wenn wir nicht eh schon im dnd sind.
            {
                dragndrop = true;
                chatBox.schreiben("Dragndrop Modus gestartet.\n");
                // Schauen, ob der Klick im Bereich der Leiste liegt.
                if ((mx > qBarPos.X) && (my > qBarPos.Y))
                {
                    // Schauen, welcher Slot der Leiste getroffen wurde.
                    bool slotgefunden = false;
                    int slotzaehler = 0;
                    while (!slotgefunden && (slotzaehler < 10))
                    {
                        if (slotDestination[slotzaehler].Contains(new Point(mx, my)))
                        {
                            slotgefunden = true;
                            if (!leiste.isEmpty(slotzaehler))
                            {
                                mausSlot.effektBelegen(leiste.effectGeben(slotzaehler));
                                mausHatIcon = true;
                                mausIconColor = Color.White;
                                leiste.slotLeeren(slotzaehler);
                                leiste.setFarbe(slotzaehler, Color.Transparent);
                                this.guiUpdaten();
                            }
                        }
                        slotzaehler += 1;
                    }
                }
            }
        }

    }
}
